<template>
  <div class="threeD-ThreeD">
    <div class="rules">
      <div ref="threeDim"></div>
    </div>
  </div>
</template>
<script lang="ts" setup>
import * as THREE from "three";
import {OrbitControls} from "three/examples/jsm/controls/OrbitControls";
import {InitStats, FPSUpdate} from "../common/showFPSMeter";
import {onMounted, ref, reactive, nextTick, defineExpose} from "vue";
import {CreateGridHelper} from "../common/gridHelper";
import Geometry from "../common/geometry";
import RendererMousedown from "../common/rendererMousedown"
import {useThreeDimensional} from "../../../storage/models/threeDimensional"
import {Object3D} from "three/src/Three";

const threeDim = ref();

const threeDStore = useThreeDimensional();
// const defaultData = reactive({})

const scene = new THREE.Scene();
scene.name = "scene";
let camera: any = null;

let geometry: Geometry;
let rendererMousedown: RendererMousedown;

const clock = new THREE.Clock();
const FPS = 60;
const renderT = 1 / FPS;
let timeS = 0;

let controls: OrbitControls | null = null;

CreateGridHelper(scene);

const axesHelper = new THREE.AxesHelper(100);
axesHelper.name = "axesHelper"
scene.add(axesHelper);

// const point = new THREE.PointLight(0xffffff);
// point.position.set(400, 200, 300);
// scene.add(point);
//
// const ambient = new THREE.AmbientLight(0x444444);
// scene.add(ambient);

const renderer = new THREE.WebGLRenderer();

renderer.setClearColor(0x2C2C2C, 1);
// 初始化
const Init = () => {
  const width = threeDim?.value?.offsetWidth;
  const height = threeDim?.value?.offsetHeight;

  camera = new THREE.PerspectiveCamera(20, width / height, 1, 10000);
  camera.name = "camera";
  camera.position.set(0, 500, 1000);
  camera.lookAt(scene.position);
  renderer.setSize(width, height);
  threeDim.value.appendChild(renderer.domElement);

  controls = new OrbitControls(camera, renderer.domElement);
  geometry = new Geometry(renderer, scene, camera, controls);
  rendererMousedown = new RendererMousedown(renderer, scene, camera);
  renderer.domElement.addEventListener('mousedown', (event) => {
    const object3D = rendererMousedown.OnTouchMove(event, width, height, geometry.object3DList);
    if(object3D){
      // @ts-ignore
      const layerList = threeDStore.layerList[1].children
      // @ts-ignore
      const key: string = object3D['uuid'];
      for(let i = 0; i < layerList.length;i++){
        let item = layerList[i];
        if (key === item['uuid']) {
          GetObject3D(item);
          return false;
        }
      }
    }

  });
  const scenes = {...scene};
  scenes.children = []
  scene.children.forEach((item, i) => {
    if (item.name !== 'transformControl' && item.name !== 'axesHelper' && item.name !== 'gridHelperSc') {
      scenes.children.push(item);
    }
  })
  threeDStore.setLayerList([camera, scenes])
};

// 渲染
const Render = () => {
  requestAnimationFrame(Render);
  const T = clock.getDelta();
  timeS = timeS + T;
  if (timeS > renderT) {
    renderer.render(scene, camera);
    FPSUpdate()
    // rendererMousedown.EffectComposerRender();
    timeS = 0;
  }
};

// 鼠标事件
const Mouse = () => {
  // controls.addEventListener("change", Render);
};
// 界面发生改变
const OnResize = () => {
  const width = threeDim?.value?.offsetWidth;
  const height = threeDim?.value?.offsetHeight;
  camera.aspect = width / height;
  camera.updateProjectionMatrix();
  renderer.setSize(width, height);
};
// 添加建模
const AddGeometry = (type: string) => {
  switch (type.toString()) {
    case "boxGeometry":
      geometry.AddBoxGeometry();
      break;
    case "circleGeometry":
      geometry.AddCircleGeometry();
      break;
    case "coneGeometry":
      geometry.AddConeGeometry();
      break;
    case "cylinderGeometry":
      geometry.AddCylinderGeometry();
      break;
    case "sphereGeometry":
      geometry.AddSphereGeometry();
      break;
    case "torusGeometry":
      geometry.AddTorusGeometry();
      break;
    case "torusKnotGeometry":
      geometry.AddTorusKnotGeometry();
      break;
    case "planeGeometry":
      geometry.AddPlaneGeometry();
      break;
  }
}
const GetObject3D = (data:Object3D) => {
  geometry.GetObject3D(data);
}
onMounted(() => {
  nextTick(async () => {
    await Init();
    await Mouse();
    await InitStats(threeDim.value);
    await Render();
  });
  window.addEventListener("resize", OnResize);
});

defineExpose({
  AddGeometry,
  GetObject3D
})
</script>
<style lang="less" scoped>
.threeD-ThreeD {
  width: 100%;
  height: 100%;
  overflow: auto;

  > .rules {
    position: relative;
    width: 100%;
    height: 100%;

    > div {
      width: 100%;
      height: 100%;

      > canvas {
        width: 100%;
        height: 100%;
      }

    }
  }
}
</style>
